package org.smog.core.config.mybatis;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.session.SqlSession;
import org.smog.core.domain.entity.IEntity;
import org.smog.core.util.AutoMapUtils;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;

/**
 * @Description: Created by IntelliJ IDEA.
 * @project_name: smogTemp
 * @time: 2020-05-16 10:45
 * @email: 17685306043@163.com
 * @author: huangZhongYao
 */
public interface IMybatisBaseMapper<TEntity extends IEntity> extends BaseMapper<TEntity> {

    /**
     * 批量插入
     *
     * @param entityList  插入列表
     * @param batchSize   插入列表size
     * @param insertClass 插入实体 class
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    default boolean insertBatch(Collection<TEntity> entityList, int batchSize, Class<?> insertClass) {
        String sqlStatement = SqlHelper.table(insertClass).getSqlStatement(SqlMethod.INSERT_ONE.getMethod());
        SqlSession batchSqlSession = SqlHelper.sqlSessionBatch(insertClass);
        Throwable var6 = null;

        try {
            int i = 0;

            for (Iterator var8 = entityList.iterator(); var8.hasNext(); ++i) {
                IEntity anEntityList = (IEntity) var8.next();
                batchSqlSession.insert(sqlStatement, anEntityList);
                if (i >= 1 && i % batchSize == 0) {
                    batchSqlSession.flushStatements();
                }
            }
            batchSqlSession.flushStatements();
            return true;
        } catch (Throwable var17) {
            var6 = var17;
            throw var17;
        } finally {
            if (batchSqlSession != null) {
                if (var6 != null) {
                    try {
                        batchSqlSession.close();
                    } catch (Throwable var16) {
                        var6.addSuppressed(var16);
                    }
                } else {
                    batchSqlSession.close();
                }
            }
        }
    }

    /**
     * 分页查询 转换成指定类型
     *
     * @param pageIndex    页码
     * @param pageSize     条目数
     * @param queryWrapper 查询条件
     * @param uClass       转换的目标类型
     * @param <U>          返回类型
     * @return
     */
    default <U> IPage<U> selectPage(long pageIndex, long pageSize, Wrapper<TEntity> queryWrapper, Class<U> uClass) {
        Page page = new Page(pageIndex, pageSize);
        IPage pageResult = this.selectPage(page, queryWrapper);
        pageResult.setRecords(AutoMapUtils.mapList(pageResult.getRecords(), uClass));
        return pageResult;
    }

    /**
     * 分页查询 转换成指定类型 进行处理
     *
     * @param pageIndex    页码
     * @param pageSize     条目数
     * @param queryWrapper 查询条件
     * @param func         函数处理
     * @param <U>          转换的目标类型
     * @return
     */
    default <U> IPage<U> selectPage(long pageIndex, long pageSize, Wrapper<TEntity> queryWrapper, Function<List<TEntity>, List<U>> func) {
        Page page = new Page(pageIndex, pageSize);
        IPage pageResult = this.selectPage(page, queryWrapper);
        List<U> apply = (List) func.apply(pageResult.getRecords());
        pageResult.setRecords(apply);
        return pageResult;
    }


    /**
     * 条件查询列表,进行函数处理并转为指定类型
     *
     * @param queryWrapper 查询条件
     * @param func         函数处理
     * @param uClass       目标类型
     * @param <U>          返回类型
     * @return
     */
    default <U> List<U> selectList(Wrapper<TEntity> queryWrapper, Class<U> uClass, Function<List<TEntity>, List<U>> func) {
        List<TEntity> list = this.selectList(queryWrapper);
        return func.apply(list);
    }

    /**
     * 条件查询列表,进行函数处理
     *
     * @param queryWrapper 查询条件
     * @param func         函数处理
     * @return
     */
    default List<TEntity> selectList(Wrapper<TEntity> queryWrapper, Function<List<TEntity>, List<TEntity>> func) {
        List<TEntity> list = this.selectList(queryWrapper);
        return func.apply(list);
    }

    /**
     * 条件查询列表,转换成指定类型
     *
     * @param queryWrapper 查询条件
     * @param uClass       转换的目标类型
     * @return
     */
    default <U> List<U> selectList(Wrapper<TEntity> queryWrapper, Class<U> uClass) {
        List<TEntity> list = this.selectList(queryWrapper);
        return AutoMapUtils.mapList(list, uClass);
    }
}
